﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using Dapper;
using Learun.Util;

namespace Learun.DataBase.Repository
{
    /// <summary>
    /// 仓储类。
    /// </summary>
    public class Repository : IRepository
    {
        /// <summary>
        /// 有点类似于全局的一个where条件
        /// </summary>
        private DbWhere dbWhere = (DbWhere)WebHelper.GetHttpItems("DataAhthorCondition");

        public IDatabase db;

        public Repository(IDatabase idatabase)
        {
            this.db = idatabase;
        }

        public DbConnection getDbConnection()
        {
            return this.db.getDbConnection();
        }

        public IRepository BeginTrans()
        {
            this.db.BeginTrans();
            return this;
        }

        public void Commit()
        {
            this.db.Commit();
        }

        public void Rollback()
        {
            this.db.Rollback();
        }

        public int ExecuteBySql(string strSql)
        {
            return this.db.ExecuteBySql(strSql);
        }

        public int ExecuteBySql(string strSql, object dbParameter)
        {
            return this.db.ExecuteBySql(strSql, dbParameter);
        }

        public int ExecuteByProc(string procName)
        {
            return this.db.ExecuteByProc(procName);
        }

        public int ExecuteByProc(string procName, object dbParameter)
        {
            return this.db.ExecuteByProc(procName, dbParameter);
        }

        public T ExecuteByProc<T>(string procName) where T : class
        {
            return this.db.ExecuteByProc<T>(procName);
        }

        public T ExecuteByProc<T>(string procName, object dbParameter) where T : class
        {
            return this.db.ExecuteByProc<T>(procName, dbParameter);
        }

        public IEnumerable<T> QueryByProc<T>(string procName) where T : class
        {
            return this.db.QueryByProc<T>(procName);
        }

        public IEnumerable<T> QueryByProc<T>(string procName, object dbParameter) where T : class
        {
            return this.db.QueryByProc<T>(procName, dbParameter);
        }

        public int Insert<T>(T entity) where T : class
        {
            return this.db.Insert<T>(entity);
        }

        public int InsertByNoMap<T>(T entity, string tablename) where T : class
        {
            return this.db.InsertByNoMap<T>(entity, tablename);
        }
        public int InsertByNoMap<T>(List<T> entities, string tablename) where T : class
        {
            return this.db.InsertByNoMap<T>(entities, tablename);
        }
        public int Insert<T>(List<T> entity) where T : class
        {
            return this.db.Insert<T>(entity);
        }

        public int Delete<T>(T entity) where T : class
        {
            return this.db.Delete<T>(entity);
        }

        public int Delete<T>(List<T> entity) where T : class
        {
            return this.db.Delete<T>(entity);
        }

        public int Delete<T>(Expression<Func<T, bool>> condition) where T : class, new()
        {
            return this.db.Delete<T>(condition);
        }

        public int Update<T>(T entity) where T : class
        {
            return this.db.Update<T>(entity);
        }

        public int UpdateByNoMap<T>(T entity, string tablename, string pkcolumn) where T : class
        {
            return this.db.UpdateByNoMap<T>(entity, tablename, pkcolumn);
        }

        public int UpdateByNoMap<T>(List<T> entities, string tablename, string pkcolumn) where T : class
        {
            return this.db.UpdateByNoMap<T>(entities, tablename, pkcolumn);
        }

        public int UpdateEx<T>(T entity) where T : class
        {
            return this.db.UpdateEx<T>(entity);
        }

        public int Update<T>(List<T> entity) where T : class
        {
            return this.db.Update<T>(entity);
        }

        /// <summary>
        /// 仓储下的方法。根据主键找一个实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public T FindEntity<T>(object keyValue) where T : class
        {
            return this.db.FindEntity<T>(keyValue);
        }

        public T FindEntity<T>(Expression<Func<T, bool>> condition) where T : class, new()
        {
            return this.db.FindEntity<T>(condition);
        }

        /// <summary>
        /// 仓储下的方法。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strSql"></param>
        /// <param name="dbParameter"></param>
        /// <returns></returns>
        public T FindEntity<T>(string strSql, object dbParameter) where T : class, new()
        {
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dynamicParameters = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                dynamicParameters.AddDynamicParams(dbParameter);
                return this.db.FindEntity<T>(strSql, dynamicParameters);
            }
            return this.db.FindEntity<T>(strSql, dbParameter);
        }

        public IQueryable<T> IQueryable<T>() where T : class, new()
        {
            return this.db.IQueryable<T>();
        }

        public IQueryable<T> IQueryable<T>(Expression<Func<T, bool>> condition) where T : class, new()
        {
            return this.db.IQueryable<T>(condition);
        }

        public IEnumerable<T> FindList<T>() where T : class, new()
        {
            return this.db.FindList<T>();
        }

        public IEnumerable<T> FindList<T>(string strSql) where T : class
        {
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dbParameter = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                return this.db.FindList<T>(strSql, dbParameter);
            }
            return this.db.FindList<T>(strSql);
        }

        public IEnumerable<T> FindList<T>(string strSql, object dbParameter) where T : class
        {
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dynamicParameters = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                dynamicParameters.AddDynamicParams(dbParameter);
                return this.db.FindList<T>(strSql, dynamicParameters);
            }
            return this.db.FindList<T>(strSql, dbParameter);
        }

        public IEnumerable<T> FindList<T>(Pagination pagination) where T : class, new()
        {
            int records = pagination.records;
            if (string.IsNullOrEmpty(pagination.sidx))
            {
                pagination.sidx = "";
                pagination.sord = "asc";
            }
            IEnumerable<T> arg_6B_0 = this.db.FindList<T>(pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
            pagination.records = records;
            return arg_6B_0;
        }

        public IEnumerable<T> FindList<T>(Expression<Func<T, bool>> condition, Pagination pagination) where T : class, new()
        {
            int records = pagination.records;
            if (string.IsNullOrEmpty(pagination.sidx))
            {
                pagination.sidx = "";
                pagination.sord = "asc";
            }
            IEnumerable<T> arg_6C_0 = this.db.FindList<T>(condition, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
            pagination.records = records;
            return arg_6C_0;
        }

        public IEnumerable<T> FindList<T>(Expression<Func<T, bool>> condition) where T : class, new()
        {
            return this.db.FindList<T>(condition);
        }

        public IEnumerable<T> FindList<T>(string strSql, Pagination pagination) where T : class
        {
            int records = pagination.records;
            if (string.IsNullOrEmpty(pagination.sidx))
            {
                pagination.sidx = "";
                pagination.sord = "asc";
            }
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dbParameter = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                IEnumerable<T> arg_E3_0 = this.db.FindList<T>(strSql, dbParameter, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
                pagination.records = records;
                return arg_E3_0;
            }
            IEnumerable<T> arg_126_0 = this.db.FindList<T>(strSql, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
            pagination.records = records;
            return arg_126_0;
        }

        public IEnumerable<T> FindList<T>(string strSql, object dbParameter, Pagination pagination) where T : class
        {
            int records = pagination.records;
            if (string.IsNullOrEmpty(pagination.sidx))
            {
                pagination.sidx = "";
                pagination.sord = "asc";
            }
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dynamicParameters = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                dynamicParameters.AddDynamicParams(dbParameter);
                IEnumerable<T> arg_EA_0 = this.db.FindList<T>(strSql, dynamicParameters, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
                pagination.records = records;
                return arg_EA_0;
            }
            IEnumerable<T> arg_12E_0 = this.db.FindList<T>(strSql, dbParameter, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
            pagination.records = records;
            return arg_12E_0;
        }

        public DataTable FindTable(string strSql)
        {
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                return this.db.FindTable(strSql, SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters));
            }
            return this.db.FindTable(strSql);
        }

        public DataTable FindTable(string strSql, object dbParameter)
        {
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dynamicParameters = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                dynamicParameters.AddDynamicParams(dbParameter);
                return this.db.FindTable(strSql, dynamicParameters);
            }
            return this.db.FindTable(strSql, dbParameter);
        }

        public DataTable FindTable(string strSql, Pagination pagination)
        {
            int records = pagination.records;
            DataTable result;
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dbParameter = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                result = this.db.FindTable(strSql, dbParameter, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
            }
            else
            {
                result = this.db.FindTable(strSql, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
            }
            pagination.records = records;
            return result;
        }

        public DataTable FindTable(string strSql, object dbParameter, Pagination pagination)
        {
            int records = pagination.records;
            DataTable result;
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dynamicParameters = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                dynamicParameters.AddDynamicParams(dbParameter);
                result = this.db.FindTable(strSql, dynamicParameters, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
            }
            else
            {
                result = this.db.FindTable(strSql, dbParameter, pagination.sidx, pagination.sord.ToLower() == "asc", pagination.rows, pagination.page, out records);
            }
            pagination.records = records;
            return result;
        }

        public object FindObject(string strSql)
        {
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dbParameter = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                return this.db.FindObject(strSql, dbParameter);
            }
            return this.db.FindObject(strSql);
        }

        public object FindObject(string strSql, object dbParameter)
        {
            if (this.dbWhere != null)
            {
                int num = strSql.ToUpper().IndexOf("ORDER BY");
                if (num > 0)
                {
                    strSql = strSql.Substring(0, num);
                    string arg = strSql.Substring(num);
                    strSql = string.Format(" select * From ({0})t Where {1} {2} ", strSql, this.dbWhere.sql, arg);
                }
                else
                {
                    strSql = string.Format(" select * From ({0})t Where {1} ", strSql, this.dbWhere.sql);
                }
                DynamicParameters dynamicParameters = SqlHelper.FieldValueParamToParameter(this.dbWhere.dbParameters);
                dynamicParameters.AddDynamicParams(dbParameter);
                return this.db.FindObject(strSql, dynamicParameters);
            }
            return this.db.FindObject(strSql, dbParameter);
        }

        public IEnumerable<T> GetDBTable<T>() where T : class, new()
        {
            return this.db.GetDBTable<T>();
        }

        public IEnumerable<T> GetDBTableFields<T>(string tableName) where T : class, new()
        {
            return this.db.GetDBTableFields<T>(tableName);
        }
    }
}
